!function ($) {
    var ListControl = function (element, options) {
        this.target_el = "#" + element.id;
        if (options) _.extend(this, options);
    };

    ListControl.prototype = {
        constructor:ListControl,
        storageId: "list_control",
        removableItems: false,
        items:[],
        itemsById:{},

        GetOrderedList: function() {
            return _.map($(this.target_el + " div"), function(li) {
                return this.itemsById[li.id];
            }, this);
        },

        AddItem: function(newitem) {
            if (!newitem) return false;
            if (this.items.indexOf(newitem) >= 0) return false;
            this.items.push(newitem);

            var item_id = ("li_" + Math.random()).replace(".", "");
            this.itemsById[item_id] = newitem;

            var html = "<div id='" + item_id + "'>" + newitem;
            if (this.removableItems) {
                html += " <span class='item-remover'>x</span>";
            }
            html += "</div>";
            $(this.target_el).append(html);

            var me = this;
            $(".item-remover").click(function(ev) {
                if (ev && ev.target) me._removeItem(ev.target.parentNode);
            });

            return true;
        },

        ResetItems:function () {
            this.itemsById = {};
            this.items = [];
            localStorage.removeItem(this.storageId);
            $(this.target_el).empty();

            $.when(this.LoadLists()).done(function() {
                $(this.target_el).trigger( jQuery.Event("removed-items") );
            }, this);
        },

        LoadLists:function () {
            // TODO : Lookup lists from URL, localStorage, remoteService and load in menu

            if (this._loadFromLocal()) return;

            if (!this.url) return;

            return $.ajax({
                "url": this.url,
                "method": "GET",
                "context": this,
                "success": function(txt) {
                    _.each(txt.split("\n"), this.AddItem, this);
                }
            });
        },

        _loadFromLocal:function () {
            var newitems = localStorage.getItem(this.storageId);
            if (newitems) {
                _.each(newitems.split(","), this.AddItem, this);
                return true;
            }
            return false;
        },

        _saveLocal:function () {
            localStorage.removeItem(this.storageId);
            localStorage.setItem(this.storageId, this.GetOrderedList().join(","));
        },

        _removeItem:function (itemLI) {
            if (!itemLI) return;

            var item = this.itemsById[itemLI.id];
            if (!item) return;

            this.itemsById[itemLI.id] = null;

            var itemsIdx = this.items.indexOf(item);
            if (itemsIdx >= 0) this.items.splice(itemsIdx, 1);

            $("#" + itemLI.id).remove();

            $(this.target_el).trigger( jQuery.Event("removed-item") );
        }
    };

    // jQuery Plugin
    $.fn.listcontrol = function (options) {
        var loadList = null;
        this.each(function () {
            var $this = $(this);
            var ft = $this.data("ListControl");
            if (!ft) $this.data("ListControl", (ft = new ListControl(this, options)));
            loadList = ft.LoadLists();
        });
        return loadList;
    };

    $.fn.add_item = function (newitem) {
        return this.each(function () {
            var lc = $(this).data("ListControl");
            if (lc) lc.AddItem(newitem);
        });
    };

    $.fn.save_items = function () {
        return this.each(function () {
            var lc = $(this).data("ListControl");
            if (lc) lc._saveLocal();
        });
    };

    $.fn.reset_items = function () {
        return this.each(function () {
            var lc = $(this).data("ListControl");
            if (lc) lc.ResetItems();
        });
    };

    $.fn.ordered_list = function () {
        var items = [];
        this.each(function () {
            var lc = $(this).data("ListControl");
            if (lc) items = lc.GetOrderedList();
        });
        return items;
    };
}(window.jQuery);
